
package com.scs.application.modules.base.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.scs.application.consts.RoleConsts;
import com.scs.application.consts.SerialRuleConsts;
import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.serial.SerialUtils;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.PinYinUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.modules.base.entity.Hospital;
import com.scs.application.modules.base.mapper.HospitalMapper;
import com.scs.application.modules.base.request.HospitalQueryRequest;
import com.scs.application.modules.base.service.HospitalService;
import com.scs.application.modules.upms.entity.Office;
import com.scs.application.modules.upms.service.OfficeService;
import com.scs.application.modules.upms.service.UserService;
import com.scs.application.modules.upms.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;


/**
 * 医院 service 实现
 */

@Slf4j
@Service
public class HospitalServiceImpl extends BaseServiceImpl<HospitalMapper, Hospital> implements HospitalService {

    @Autowired
    public OfficeService officeService;

    @Autowired
    public UserService userService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveCascadeById(Hospital entity) {
        List<Hospital> loginKeys = this.list(Wrappers.<Hospital>query()
                .eq("login_key", entity.getLoginKey())
        );
        if (loginKeys.size() != 0) {
            throw new BusinessException("登录账号已存在，请修改登录账号再试");
        }

        // 添加用户，供应商编号作为主账户
        String hospitalCode = SerialUtils.generateCode(SerialRuleConsts.BASE_HOSPITAL_CODE);
        entity.setCode(hospitalCode);
        if (StringUtils.isBlank(entity.getPinyin())) {
            entity.setPinyin(PinYinUtils.getPinYin(entity.getName()));
        }


        // 添加机构
        Office office = new Office();
        office.setCode(entity.getCode()).setType(Office.TYPE_HOSPITAL).setSort(1l)
                .setName(entity.getName()).setParentId("0");
        officeService.save(office);

        entity.setOfficeId(office.getId());

        UserVO userVO = new UserVO();
        userVO.setOfficeId(office.getId())
                .setLoginKey(entity.getLoginKey())
                .setNickname(entity.getName())
                .setEmail(entity.getEmail())
                .setMobile(entity.getMobile())
                .setRoleCodes(Lists.newArrayList(RoleConsts.HOSPITAL_MANAGER))
                .setRemark("医院" + entity.getName() + "主账号");
        userService.addUser(userVO);
        return super.saveCascadeById(entity);
    }

    @Override
    public boolean updateCascadeById(Hospital entity) {
        entity.setCode(null).setOfficeId(null);
        return super.updateCascadeById(entity);
    }


    @Override
    public Hospital findByOfficeId(String officeId) {
        return this.getOne(Wrappers.<Hospital>query().eq("office_id", officeId));
    }

    @Override
    public IPage<Hospital> page(HospitalQueryRequest request) {
        IPage page = this.page(request.getPage(), Wrappers.<Hospital>query()
                .like(StringUtils.isNotBlank(request.getCode()), "code", request.getCode())
                .like(StringUtils.isNotBlank(request.getName()), "name", request.getName())
                .orderByDesc("gmt_modified"));
        return page;
    }


    @Override
    public List<Hospital> list(HospitalQueryRequest request) {
        List<Hospital> list = this.list(Wrappers.<Hospital>query()
                .orderByDesc("gmt_modified")
        );
        return list;
    }

    @Override
    public IPage<Hospital> pageByKeywords(HospitalQueryRequest request, String keywords) {
        IPage page = this.page(request.getPage(), Wrappers.<Hospital>query()
                .like(StringUtils.isNotBlank(keywords), "name", keywords)
                .orderByDesc("gmt_modified")
        );
        return page;
    }

    /**
     * @description: 外部系统调用-新增
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addBatchFromTpc(List<Hospital> dataList) {
        if (dataList.isEmpty()) {
            return "校验异常,传入数据为空";
        }
        dataList.stream().filter(item -> StringUtils.isBlank(item.getOid())).findFirst().ifPresent(find -> {
            BusinessException.throwError("校验异常,组织机构代码为空,机构:{}",find.getName());
        });

        List<String> oidList = dataList.stream().map(Hospital::getOid).collect(Collectors.toList());
        if (oidList.size() != oidList.stream().distinct().collect(Collectors.toList()).size()) {
            dataList.stream().forEach(item -> {
                if (oidList.indexOf(item.getOid()) != oidList.lastIndexOf(item.getOid())) {
                    BusinessException.throwError("校验异常,组织机构代码重复,机构代码:{}",item.getOid());
                }
            });
        }

        List<String> oidDbList = this.list(Wrappers.<Hospital>query().in("oid",oidList)).stream().map(Hospital::getOid).collect(Collectors.toList());

        dataList = dataList.stream().filter(item -> !oidDbList.contains(item.getOid())).collect(Collectors.toList());
        if (dataList.isEmpty()) {
            return "没有可新增的机构";
        }

        dataList.stream().forEach(item -> {
            item.setLoginKey(item.getOid());
            this.saveCascadeById(item);
        });

        return StrUtil.format("新增机构数量{}",dataList.size());
    }
}
